#pragma once

#include "../umlmodel_global.h"

#include <memory>
#include <vector>

#include "PackageableElement.h"

using std::make_shared;
using std::shared_ptr;
using std::vector;

namespace uml {
class Classifier;
class Generalization;

/// <summary>
/// GeneralizationSet
/// A GeneralizationSet is a PackageableElement whose instances represent sets of
/// Generalization relationships.
/// </summary>
class UMLMODEL_EXPORT GeneralizationSet : public PackageableElement {

public: // Constructors and destructors
    explicit GeneralizationSet(const QString& umlType="uml::GeneralizationSet");

public: // JsonSerializable override
    void fromJson(const QJsonObject& json, QStringList& errorList) override;
    void toJson(QJsonObject& json) override;

public: // Properties
    /// <summary>
    /// generalizations getter
    /// Designates the instances of Generalization that are members of this
    /// GeneralizationSet.
    /// </summary>
    vector<shared_ptr<Generalization>>& generalizations();

    /// <summary>
    /// isCovering getter
    /// Indicates (via the associated Generalizations) whether or not the set of
    /// specific Classifiers are covering for a particular general classifier. When
    /// isCovering is true, every instance of a particular general Classifier is also an
    /// instance of at least one of its specific Classifiers for the GeneralizationSet.
    /// When isCovering is false, there are one or more instances of the particular
    /// general Classifier that are not instances of at least one of its specific
    /// Classifiers defined for the GeneralizationSet.
    /// </summary>
    bool isCovering() const;

    /// <summary>
    /// isCovering setter
    /// Indicates (via the associated Generalizations) whether or not the set of
    /// specific Classifiers are covering for a particular general classifier. When
    /// isCovering is true, every instance of a particular general Classifier is also an
    /// instance of at least one of its specific Classifiers for the GeneralizationSet.
    /// When isCovering is false, there are one or more instances of the particular
    /// general Classifier that are not instances of at least one of its specific
    /// Classifiers defined for the GeneralizationSet.
    /// </summary>
    void setIsCovering(bool value);

    /// <summary>
    /// isDisjoint getter
    /// Indicates whether or not the set of specific Classifiers in a Generalization
    /// relationship have instance in common. If isDisjoint is true, the specific
    /// Classifiers for a particular GeneralizationSet have no members in common; that
    /// is, their intersection is empty. If isDisjoint is false, the specific
    /// Classifiers in a particular GeneralizationSet have one or more members in
    /// common; that is, their intersection is not empty.
    /// </summary>
    bool isDisjoint() const;

    /// <summary>
    /// isDisjoint setter
    /// Indicates whether or not the set of specific Classifiers in a Generalization
    /// relationship have instance in common. If isDisjoint is true, the specific
    /// Classifiers for a particular GeneralizationSet have no members in common; that
    /// is, their intersection is empty. If isDisjoint is false, the specific
    /// Classifiers in a particular GeneralizationSet have one or more members in
    /// common; that is, their intersection is not empty.
    /// </summary>
    void setIsDisjoint(bool value);

    /// <summary>
    /// powertype getter
    /// Designates the Classifier that is defined as the power type for the associated
    /// GeneralizationSet, if there is one.
    /// </summary>
    shared_ptr<Classifier> powertype() const;

    /// <summary>
    /// powertype setter
    /// Designates the Classifier that is defined as the power type for the associated
    /// GeneralizationSet, if there is one.
    /// </summary>
    void setPowertype(shared_ptr<Classifier> value);

private: // Fields
    /// <summary>
    /// generalizations
    /// Designates the instances of Generalization that are members of this
    /// GeneralizationSet.
    /// </summary>
    vector<shared_ptr<Generalization>> generalizations_;

    /// <summary>
    /// isCovering
    /// Indicates (via the associated Generalizations) whether or not the set of
    /// specific Classifiers are covering for a particular general classifier. When
    /// isCovering is true, every instance of a particular general Classifier is also an
    /// instance of at least one of its specific Classifiers for the GeneralizationSet.
    /// When isCovering is false, there are one or more instances of the particular
    /// general Classifier that are not instances of at least one of its specific
    /// Classifiers defined for the GeneralizationSet.
    /// </summary>
    const static bool isCovering_default_;
    bool isCovering_= isCovering_default_;

    /// <summary>
    /// isDisjoint
    /// Indicates whether or not the set of specific Classifiers in a Generalization
    /// relationship have instance in common. If isDisjoint is true, the specific
    /// Classifiers for a particular GeneralizationSet have no members in common; that
    /// is, their intersection is empty. If isDisjoint is false, the specific
    /// Classifiers in a particular GeneralizationSet have one or more members in
    /// common; that is, their intersection is not empty.
    /// </summary>
    const static bool isDisjoint_default_;
    bool isDisjoint_= isDisjoint_default_;

    /// <summary>
    /// powertype
    /// Designates the Classifier that is defined as the power type for the associated
    /// GeneralizationSet, if there is one.
    /// </summary>
    shared_ptr<Classifier> powertype_;

};

} // namespace uml
